#include "dma.h"

void DMA1_Init(void)
{
    // 1. 开启时钟
    RCC->AHBENR |= RCC_AHBENR_DMA1EN;

    // 2. DMA相关配置
    // 2.1 数据传输方向: 存储器<->外设 
    DMA1_Channel4->CCR &= ~DMA_CCR4_MEM2MEM;
    DMA1_Channel4->CCR |= DMA_CCR4_DIR;    // 从存储器读

    // 2.2 数据宽度: 8位 - 00
    DMA1_Channel4->CCR &= ~DMA_CCR4_PSIZE;
    DMA1_Channel4->CCR &= ~DMA_CCR4_MSIZE;

    // 2.3 地址自增：开启自增
    DMA1_Channel4->CCR &= ~DMA_CCR4_PINC;
    DMA1_Channel4->CCR |= DMA_CCR4_MINC;

    // 2.4 开启数据传输完成中断标志
    DMA1_Channel4->CCR |= DMA_CCR4_TCIE;

    // 2.5 使能串口的DMA传输功能
    USART1->CR3 |= USART_CR3_DMAT;

    // 3. NVIC配置
    NVIC_SetPriorityGrouping(3);
    NVIC_SetPriority(DMA1_Channel4_IRQn, 2);
    NVIC_EnableIRQ(DMA1_Channel4_IRQn);
}

void DMA1_Transmit(const uint8_t *p_src, uint8_t *p_dst, uint16_t dataLen)
{
    // 1. 设置外设地址
    DMA1_Channel4->CPAR = (uint32_t)p_dst;

    // 2. 设置存储器地址
    DMA1_Channel4->CMAR = (uint32_t)p_src;

    // 3. 设置传输的数据量
    DMA1_Channel4->CNDTR = dataLen;

    // 4. 开启通道，开始传输数据
    DMA1_Channel4->CCR |= DMA_CCR4_EN;
}

// 中断服务程序
void DMA1_Channel4_IRQHandler(void)
{
    // 判断中断标志位
    if (DMA1->ISR & DMA_ISR_TCIF4)
    {
        // 清除中断标志位
        DMA1->IFCR |= DMA_IFCR_CTCIF4;

        // 关闭DMA通道
        DMA1_Channel4->CCR &= ~DMA_CCR4_EN;
    }
}

